package com.glodon.paas.activity.biz;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.glodon.paas.activity.dao.ActivityDao;
import com.glodon.paas.activity.dao.domain.ActivityDefinitionEntity;
import com.glodon.paas.activity.dao.domain.ActivityEntity;
import com.glodon.paas.activity.util.ActivityEntityHelp;
import com.glodon.paas.activity.util.ActivityTemplateMerger;
import com.glodon.paas.exception.PaasServerExceptionFactory;
import static com.glodon.paas.util.ParamaterHelper.*;
import com.glodon.paas.util.UUIDUtil;
import com.glodon.paas.util.asyn.AsynWorker;

@Component("activityBiz")
public class ActivityBiz {

    private static Logger logger = LoggerFactory.getLogger(ActivityBiz.class);
    @Autowired
    ActivityDao           activityDao;
    @Autowired
    ActivityDefinitionBiz activityDefinitionBiz;
    @Autowired
    AsynWorker            asynWorker;
    @Autowired
    AccountClient         accountClient;

    public ActivityEntity insert(ActivityEntity entity) {
        entity.setId(UUIDUtil.getUUIDStr());
        entity.setCreateTime(new Date());
        activityDao.insertSelective(entity);
        return entity;
    }

    public ActivityEntity selectById(String id) {
        return activityDao.selectByPrimaryKey(id);
    }

    /**
     * @param userId        活动接收者ID
     * @param appId
     * @param moduleId
     * @param activityType
     * @param itemId
     * @param itemType
     * @param subItemId
     * @param actorId       发送者ID
     * @param earlierTime   较新的时间,毫秒
     * @param laterTime     较早的时间,毫秒
     * @param count         需要查询记录数
     * @param needRender    是否 需要使用模板渲染：值可以是true，false，1，0
     * @return
     */
    public List<ActivityEntity> query(Map<String, String> params) {

        String receiverId = getString("receiverId", null, params, exceptionIfAbsent);
        Integer appId = getInteger("appId", null, params, !exceptionIfAbsent, exceptionIfUnMatch);
        Integer moduleId = getInteger("moduleId", null, params, !exceptionIfAbsent, exceptionIfUnMatch);
        Long activityType = getLong("activityType", null, params, !exceptionIfAbsent, exceptionIfUnMatch);
        String itemId = getString("itemId", null, params, !exceptionIfAbsent);
        String itemType = getString("itemType", null, params, !exceptionIfAbsent);
        String subItemId = getString("subItemId", null, params, !exceptionIfAbsent);
        String actorId = getString("actorId", null, params, !exceptionIfAbsent);
        Integer count = getInteger("count", 50, params, !exceptionIfAbsent, !exceptionIfUnMatch);
        Boolean needRender = getBoolean("needRender", true, params, !exceptionIfAbsent, !exceptionIfUnMatch);
        long nearerTime = getLong("nearerTime", 0L, params, !exceptionIfAbsent, !exceptionIfUnMatch);
        long olderTime = getLong("olderTime", 0L, params, !exceptionIfAbsent, !exceptionIfUnMatch);
        // 时间范围 day,week,month
        // String timeRange = getString("timeRange", null, params, !exceptionIfAbsent);
        
        List<ActivityEntity> list = activityDao.select(receiverId, appId, moduleId, activityType, itemId, itemType,
                                                subItemId, actorId, nearerTime, olderTime, count);
        if (needRender) {
            for (ActivityEntity activity : list) {
                ActivityDefinitionEntity def = activityDefinitionBiz.getByActivityType(activity.getActivityType());
                String displayContent = null;
                displayContent = "no definition";
                if (def != null && def.getTemplate() != null) {
                    try {
                        displayContent = ActivityTemplateMerger.mergeTemplate(activity, def.getTemplate());
                    } catch (Exception e) {
                        // String errorId = UUIDUtil.getUUIDStr(); //errorId用于快速查询错误日志
                        displayContent = "merge error:" + UUIDUtil.getUUIDStr();
                        logger.error(displayContent, e);
                    }
                } else {
                    displayContent = "no template";
                }

                activity.setDisplayContent(displayContent);
            }
        }
        return list;
    }

    /**
     * 活动发布入口，做基本处理后提交到线程池处理
     * 
     * @param entity
     */
    public void publish(ActivityEntity entity, Set<String> receiverIds) {
        if(receiverIds == null){
            receiverIds = new HashSet<String>();
        }
        
        entity.setReceiveTime(new Date());
        Long activityType = entity.getActivityType();
        
        logger.debug("server recevied:ActivityType={}", activityType);

        if (activityType == null) {
            logger.warn("activityType is null");
            throw PaasServerExceptionFactory.validateException("activityType is null", null);
        }

        ActivityDefinitionEntity def = activityDefinitionBiz.getByActivityType(activityType);
        if (def == null) {
            // 活动没有定义
            logger.warn("no ActivityDefinition for activityType:" + activityType);
            throw PaasServerExceptionFactory.validateException("no ActivityDefinition for activityType:" + activityType, null);
        }
        
        // 动态定义：不产生动态
        if(def.getStatus() == null || def.getStatus() == 0 || def.getDefaultReceiver() == null){
            logger.debug("no publish");
            return;
        }
        
        entity.setDefnition(def);

        // logger.debug("多线程异步分发动态:");
        asynWorker.submit(this, METHOD_DO_PUBLISH, new Object[] { entity, receiverIds}, null);
    }

    public static String METHOD_DO_PUBLISH = "doPublish";
    /**
     * 分发动态
     * @param entity
     * @param receiverIds
     */
    public void doPublish(ActivityEntity entity, Set<String> receiverIds) {
        /*
         * 还需要考虑的问题 ：
         * 1 actor的设置
         * 2 接收者的设置
         * 3 批量插入
         * 4 活跃用户和僵尸用户的处理
         * 5 email,手机, 通知动态
         */ 
        Set<String> receiverSet = rebuildReceiver(entity,receiverIds);

        // 保存动态
        for (String uid : receiverSet) {
            ActivityEntity newEntity =  ActivityEntityHelp.clone(entity);
            newEntity.setReceiverId(uid);
            this.insert(newEntity);
        }
    }

    /**
     * 获取活动接收者集合， 前面的操作保证这里不会出现null
     * 
     * @param entity
     * @param receiverIds
     * @return
     */
    private Set<String> rebuildReceiver(ActivityEntity entity, Set<String> receiverIds) {

        Set<String> receivers = new HashSet<String>();
        long defaultReceiver = entity.getDefnition().getDefaultReceiver();

        // 参数
        if ((defaultReceiver & 1) == 1) {
            receivers.addAll(receiverIds);
        }

        // 自己
        if ((defaultReceiver & 2) == 2) {
            receivers.add(entity.getActorId());
        }

        // 通讯录中的人
        if ((defaultReceiver & 4) == 4) {
            try {
                List<String> list = accountClient.contactId(entity.getActorId());
                receivers.addAll(list);
            } catch (Exception e) {
                logger.error("get contactId error:", e);
            }
        }
        return receivers;
    }
}
